package org.springblade.modules.auth.service.impl;


import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springblade.core.log.exception.ServiceException;
import org.springblade.core.tool.utils.Func;
import org.springblade.core.tool.utils.RedisUtil;
import org.springblade.modules.auth.dto.WeComDto;
import org.springblade.modules.auth.entity.WxAppLoginVo;
import org.springblade.modules.auth.service.IWeComService;
import org.springblade.modules.auth.utils.SsoHttpUtils;
import org.springblade.modules.system.entity.Tenant;
import org.springblade.modules.system.entity.User;
import org.springblade.modules.system.entity.UserInfo;
import org.springblade.modules.system.entity.UserOauth;
import org.springblade.modules.system.service.IUserService;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;


import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * 企微接口调用服务实现类
 *
 * @author 14866
 * @date 2023/07/11
 */
@Service
@Slf4j
@AllArgsConstructor
public class WeComServiceImpl implements IWeComService {

	/**
	 * redis 存储 accessToken key值
	 */
	private static final String REDIS_TOKEN_REDIS_KEY = "weChatAccessToken";
	/**
	 * redis
	 */
	private final RedisUtil redisCache;
	/**
	 * 获取访问令牌
	 */
	private static final String GET_ACCESS_TOKEN = "https://api.weixin.qq.com/cgi-bin/token";

	/**
	 * 获取用户信息 获取企业微信用户信息接口
	 */
	private static final String GET_USER_PHONE = "https://api.weixin.qq.com/wxa/business/getuserphonenumber" ;

	/**
	 *  获取授权用户信息URL
	 */
	private static final String JS_CODE_2_SESSION_URL = "https://api.weixin.qq.com/sns/jscode2session";
	/**
	 * 应用程序id 企业微信ID 正式环境
	 */
	private static final String APP_ID = "wx34a18e49e3f60ae0" ;
	/**
	 * 应用程序SECRET 企业微信ID 正式环境
	 */
	private static final String SECRET = "a6c6d8f3baa51118cb0c055ec3c01a61" ;

	private final IUserService userService;
	@Override
	public String getAccessToken() {
		String token;
		Map<String, Object> param = new HashMap<>(3);
		param.put("appid", APP_ID);
		param.put("secret", SECRET);
		param.put("grant_type","client_credential");
		if (redisCache.hasKey(REDIS_TOKEN_REDIS_KEY)){
			return (String) redisCache.get(REDIS_TOKEN_REDIS_KEY);
		}
		String response = SsoHttpUtils.doGet(GET_ACCESS_TOKEN, param);
		log.info("获取企微token响应信息：{}",response);
		JSONObject resJson = JSONObject.parseObject(response);

		token = resJson.getString("access_token");
		String expiresIn = resJson.getString("expires_in");
		if (null != expiresIn) {
			redisCache.set(REDIS_TOKEN_REDIS_KEY, token, Integer.parseInt(expiresIn), TimeUnit.MILLISECONDS);
		}
		return token;
	}
	@Override
	public String getUserPhone(String code, String token) {
		JSONObject jsonObject = new JSONObject();
		jsonObject.put("code", code);
		String post = SsoHttpUtils.doPost(GET_USER_PHONE + "?access_token=" + token, jsonObject);
		log.info("获取企微获取访问用户身份响应信息{}",post);
		JSONObject resJson = JSONObject.parseObject(post);
		if (!"0".equals(resJson.getString("errcode"))) {
			throw new ServiceException(resJson.getString("errmsg"));
		}
		return resJson.getJSONObject("phone_info").getString("purePhoneNumber");
	}

	/**
	 * 获取开放id
	 *
	 * @param code 代码
	 * @return {@link WxAppLoginVo}
	 */
	public WxAppLoginVo getOpenId(String code) {
		// 拼接请求参数
		StringBuilder strUrl = new StringBuilder();
		strUrl.append(JS_CODE_2_SESSION_URL)
			.append("?appid=").append(APP_ID)
			.append("&secret=").append(SECRET)
			.append("&js_code=").append(code)
			.append("&grant_type=authorization_code");
		try {
			JSONObject jsonObject = SsoHttpUtils.doGet(strUrl.toString());
			log.info("【微信小程序登录】：登录返回结果：" + jsonObject);
			WxAppLoginVo wxAppLoginVo = JSON.toJavaObject(jsonObject, WxAppLoginVo.class);
			// 这里要注意，如果请求成功是不会返回errcode的
			if (wxAppLoginVo.getErrcode() != null && wxAppLoginVo.getErrcode() != 0) {
				log.info("【微信小程序登录】：登录失败，错误码：" + wxAppLoginVo.getErrcode() + "  " + wxAppLoginVo.getErrmsg());
				throw new ServiceException(wxAppLoginVo.getErrmsg());
			}
			return wxAppLoginVo;
		} catch (Exception e) {
			log.info("【微信小程序登录】：登录异常：" + e.getMessage());
			e.printStackTrace();
			throw new ServiceException("微信小程序登录异常");
		}
	}
	@Override
	public UserInfo loginWechat(WeComDto weComDto) {
		String accessToken = getAccessToken();
		if (ObjectUtils.isEmpty(accessToken)){
			throw new ServiceException("未获取到用户token信息");
		}
		String userPhone = getUserPhone(weComDto.getCode(), accessToken);
		UserOauth userOauth = new UserOauth();
		userOauth.setUsername(userPhone);
		userOauth.setSource("yf");
		userOauth.setTenantId("000000");
		userOauth.setUuid(userPhone);
		return userService.userInfo(userOauth);
	}


}
